package com.hlhome.cllz.gyms.config;

import com.hlhome.cllz.gyms.bean.GroundScheduleJob;
import com.hlhome.cllz.gyms.bean.RefereeScheduleJob;
import org.quartz.JobDetail;
import org.quartz.Trigger;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

/**
 * 配置Quartz
 * quartz的配置类里面配置了JobDetail的工厂、Trigger的工厂和scheduler的工厂，
 * 这样的方式可以解决Job中的spring的注入bean为空的情况。
 *
 * Created by lingb on 2018/7/1
 */
@Configuration
public class QuartzConfig {

    /**
     * 配置场地定时任务，一个任务可关联多个触发器，但一个触发器只能关联一个任务，类似 班级和学生的关系
     *
     * @param   [groundScheduleJob]
     * @return  org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean
     */
    @Bean(name = "groundJobDetail")
    public MethodInvokingJobDetailFactoryBean groundJobDetail(GroundScheduleJob groundScheduleJob) {
        // ScheduleTask为需要执行的任务
        MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
        /*
         *  是否并发执行
         *  例如每5s执行一次任务，但是当前任务还没有执行完，就已经过了5s了，
         *  如果此处为true，则下一个任务会bing执行，如果此处为false，则下一个任务会等待上一个任务执行完后，再开始执行
         */
        jobDetail.setConcurrent(true);
//        // 设置任务的名字
//        jobDetail.setName("scheduler");
//        // 设置任务的分组，这些属性都可以存储在数据库中，在多任务的时候使用
//        jobDetail.setGroup("scheduler_group");

        // 为需要执行的实体类对应的对象
        jobDetail.setTargetObject(groundScheduleJob);
        // 需要执行定时执行逻辑的方法
        jobDetail.setTargetMethod("resetGround");
        return jobDetail;
    }

    /**
     * 配置场地定时任务的触发器1，也就是什么时候触发执行定时任务
     *
     * @param   [jobDetail]
     * @return  CronTriggerFactoryBean
     */
    @Bean(name = "groundJobTrigger1")
    public CronTriggerFactoryBean groundJobTrigger1(JobDetail groundJobDetail) {
        CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
        trigger.setJobDetail(groundJobDetail);
        // 设置任务启动延迟
        trigger.setStartDelay(0);
        // 初始化的cron表达式，表示每天中午12点触发
        trigger.setCronExpression("0 0 12 * * ? ");
        // trigger的name
        trigger.setName("groundJobTrigger1");
        return trigger;
    }
    /**
     * 配置场地定时任务的触发器2，也就是什么时候触发执行定时任务
     *
     * @param   [jobDetail]
     * @return  CronTriggerFactoryBean
     */
    @Bean(name = "groundJobTrigger2")
    public CronTriggerFactoryBean groundJobTrigger2(JobDetail groundJobDetail) {
        CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
        trigger.setJobDetail(groundJobDetail);
        // 设置任务启动延迟
        trigger.setStartDelay(0);
        // 初始化的cron表达式，表示每天下午6点触发
        trigger.setCronExpression("0 0 18 * * ? ");
        // trigger的name
        trigger.setName("groundJobTrigger2");
        return trigger;
    }
    /**
     * 配置场地定时任务的触发器3，也就是什么时候触发执行定时任务
     *
     * @param   [jobDetail]
     * @return  CronTriggerFactoryBean
     */
    @Bean(name = "groundJobTrigger3")
    public CronTriggerFactoryBean groundJobTrigger3(JobDetail groundJobDetail) {
        CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
        trigger.setJobDetail(groundJobDetail);
        // 设置任务启动延迟
        trigger.setStartDelay(0);
        // 初始化的cron表达式，表示每天晚上12点触发
        trigger.setCronExpression("0 0 0 * * ? ");
        // trigger的name
        trigger.setName("groundJobTrigger3");
        return trigger;
    }

    /**
     * 配置定时任务 裁判
     *
     * @param   [refereeScheduleJob]
     * @return  org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean
     */
    @Bean(name = "refereeJobDetail")
    public MethodInvokingJobDetailFactoryBean refereeJobDetail(RefereeScheduleJob refereeScheduleJob) {
        // ScheduleTask为需要执行的任务
        MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
        /*
         *  是否并发执行
         *  例如每5s执行一次任务，但是当前任务还没有执行完，就已经过了5s了，
         *  如果此处为true，则下一个任务会bing执行，如果此处为false，则下一个任务会等待上一个任务执行完后，再开始执行
         */
        jobDetail.setConcurrent(true);
//        // 设置任务的名字
//        jobDetail.setName("scheduler");
//        // 设置任务的分组，这些属性都可以存储在数据库中，在多任务的时候使用
//        jobDetail.setGroup("scheduler_group");

        // 为需要执行的实体类对应的对象
        jobDetail.setTargetObject(refereeScheduleJob);
        // 需要执行定时执行逻辑的方法
        jobDetail.setTargetMethod("resetReferee");
        return jobDetail;
    }

    /**
     * 配置裁判定时任务的触发器1，也就是什么时候触发执行定时任务
     *
     * @param   [jobDetail]
     * @return  CronTriggerFactoryBean
     */
    @Bean(name = "refereeJobTrigger1")
    public CronTriggerFactoryBean refereeJobTrigger1(JobDetail refereeJobDetail) {
        CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
        trigger.setJobDetail(refereeJobDetail);
        // 设置任务启动延迟
        trigger.setStartDelay(0);
        // 初始化的cron表达式，表示每天中午12点触发
        trigger.setCronExpression("0 0 12 * * ?");
        // trigger的name
        trigger.setName("refereeJobTrigger1");
        return trigger;

    }
    /**
     * 配置裁判定时任务的触发器2，也就是什么时候触发执行定时任务
     *
     * @param   [jobDetail]
     * @return  CronTriggerFactoryBean
     */
    @Bean(name = "refereeJobTrigger2")
    public CronTriggerFactoryBean refereeJobTrigger2(JobDetail refereeJobDetail) {
        CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
        trigger.setJobDetail(refereeJobDetail);
        // 设置任务启动延迟
        trigger.setStartDelay(0);
        // 初始化的cron表达式，表示每天下午6点触发
        trigger.setCronExpression("0 0 18 * * ?");
        // trigger的name
        trigger.setName("refereeJobTrigger2");
        return trigger;

    }
    /**
     * 配置裁判定时任务的触发器3，也就是什么时候触发执行定时任务
     *
     * @param   [jobDetail]
     * @return  CronTriggerFactoryBean
     */
    @Bean(name = "refereeJobTrigger3")
    public CronTriggerFactoryBean refereeJobTrigger3(JobDetail refereeJobDetail) {
        CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
        trigger.setJobDetail(refereeJobDetail);
        // 设置任务启动延迟
        trigger.setStartDelay(0);
        // 初始化的cron表达式，表示每天晚上12点触发
        trigger.setCronExpression("0 0 0 * * ?");
        // trigger的name
        trigger.setName("refereeJobTrigger");
        return trigger;

    }

    /**
     * 配置SchedulerFactory调度工厂
     *
     * @param   [cronJobTrigger]
     * @return  org.springframework.scheduling.quartz.SchedulerFactoryBean
     */
    @Bean(name = "scheduler")
    public SchedulerFactoryBean schedulerFactory(@Qualifier("groundJobTrigger1")Trigger groundJobTrigger1, @Qualifier("groundJobTrigger2")Trigger groundJobTrigger2, @Qualifier("groundJobTrigger3")Trigger groundJobTrigger3,
                                                 @Qualifier("refereeJobTrigger1")Trigger refereeJobTrigger1, @Qualifier("refereeJobTrigger2")Trigger refereeJobTrigger2, @Qualifier("refereeJobTrigger3")Trigger refereeJobTrigger3) {
        SchedulerFactoryBean bean = new SchedulerFactoryBean();
        //设置是否任意一个已定义的Job会覆盖现在的Job。默认为false，即已定义的Job不会覆盖现有的Job。
        bean.setOverwriteExistingJobs(true);
        // 延时启动，应用启动3秒后，定时器才开始启动
        bean.setStartupDelay(3);
        // 注册定时触发器
        bean.setTriggers(groundJobTrigger1, groundJobTrigger2, groundJobTrigger3, refereeJobTrigger1, refereeJobTrigger2, refereeJobTrigger3);
        return bean;
    }
/*

    */
/**
     * 多任务时的Scheduler，动态设置Trigger。一个SchedulerFactoryBean可能会有多个Trigger
     * @param   []
     * @return  org.springframework.scheduling.quartz.SchedulerFactoryBean
     *//*

    @Bean(name = "multitaskScheduler")
    public SchedulerFactoryBean schedulerFactoryBean(){
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        return schedulerFactoryBean;
    }
*/

}
